<template>
  <div class="app-container">
    <el-row :gutter="24">
      <!-- 左侧勤务规划区域 -->
      <el-col :span="6">
        <el-card class="box-card" style="margin-bottom: 15px">
          <div slot="header" class="clearfix">
            <span>勤务执勤规划</span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="refreshDutyPlan">重置规划</el-button>
          </div>

          <!-- 勤务规划选项 -->
          <div class="duty-plan-options">
            <el-form :model="dutyPlanForm" label-width="100px">
              <el-form-item label="勤务名称">
                <el-input v-model="dutyPlanForm.name" placeholder="请输入勤务名称"></el-input>
              </el-form-item>

              <el-form-item label="执勤方式">
                <el-select v-model="dutyPlanForm.dutyType" placeholder="选择执勤方式" style="width: 100%">
                  <el-option label="常规巡逻" value="regular_patrol"></el-option>
                  <el-option label="定点值守" value="fixed_post"></el-option>
                  <el-option label="交通管控" value="traffic_control"></el-option>
                  <el-option label="治安巡查" value="security_patrol"></el-option>
                  <el-option label="应急处突" value="emergency"></el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="勤务场景">
                <el-select v-model="dutyPlanForm.scenario" placeholder="选择勤务场景" style="width: 100%">
                  <el-option label="城区巡逻" value="urban_patrol"></el-option>
                  <el-option label="校园安防" value="campus_security"></el-option>
                  <el-option label="交通路口" value="traffic_intersection"></el-option>
                  <el-option label="商圈治安" value="commercial_security"></el-option>
                  <el-option label="特殊时段" value="special_period"></el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="勤务时段">
                <el-time-picker
                  v-model="dutyPlanForm.timeRange"
                  is-range
                  range-separator="至"
                  start-placeholder="开始时间"
                  end-placeholder="结束时间"
                  format="HH:mm"
                  style="width: 100%">
                </el-time-picker>
              </el-form-item>

              <el-form-item label="巡逻线路">
                <el-select v-model="dutyPlanForm.routeId" placeholder="选择巡逻线路" style="width: 100%" @change="handleRouteChange">
                  <el-option
                    v-for="route in mockRoutes"
                    :key="route.id"
                    :label="route.name"
                    :value="route.id">
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="巡逻点">
                <el-select v-model="dutyPlanForm.patrolPointIds" multiple placeholder="选择巡逻点" style="width: 100%">
                  <el-option
                    v-for="point in filteredPatrolPoints"
                    :key="point.id"
                    :label="point.name"
                    :value="point.id">
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item label="安保装备">
                <el-select v-model="dutyPlanForm.equipment" multiple placeholder="选择安保装备" style="width: 100%">
                  <el-option label="对讲机" value="walkie_talkie"></el-option>
                  <el-option label="防弹背心" value="bulletproof_vest"></el-option>
                  <el-option label="执法记录仪" value="law_recorder"></el-option>
                  <el-option label="警棍" value="baton"></el-option>
                  <el-option label="警用手电" value="flashlight"></el-option>
                </el-select>
              </el-form-item>

              <el-form-item>
                <el-button type="primary" @click="submitDutyPlanToAI">智能排班</el-button>
              </el-form-item>
            </el-form>
          </div>

          <!-- 巡逻线路详情 -->
          <div v-if="dutyPlanForm.routeId" class="route-detail">
            <h4>巡逻线路详情</h4>
            <div class="route-info">
              <p><strong>线路名称：</strong>{{ selectedRoute.name }}</p>
              <p><strong>线路类型：</strong>{{ formatRouteType(selectedRoute) }}</p>
              <p><strong>线路长度：</strong>{{ selectedRoute.distance }} 公里</p>
              <p><strong>预计时长：</strong>{{ selectedRoute.duration }} 分钟</p>
            </div>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧排班区域 -->
      <el-col :span="18">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>智能排班系统</span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="refreshSchedule">刷新排班</el-button>
          </div>

          <!-- 班次颜色图例 -->
          <div class="shift-legend">
            <span class="legend-title">班次图例：</span>
            <div class="legend-item">
              <span class="legend-color shift-morning"></span>
              <span class="legend-text">早班</span>
            </div>
            <div class="legend-item">
              <span class="legend-color shift-afternoon"></span>
              <span class="legend-text">中班</span>
            </div>
            <div class="legend-item">
              <span class="legend-color shift-night"></span>
              <span class="legend-text">夜班</span>
            </div>
            <div class="legend-item">
              <span class="legend-color shift-day"></span>
              <span class="legend-text">白班</span>
            </div>
            <div class="legend-item">
              <span class="legend-color shift-evening"></span>
              <span class="legend-text">晚班</span>
            </div>
            <div class="legend-item">
              <span class="legend-color shift-rest"></span>
              <span class="legend-text">休息</span>
            </div>
          </div>

          <!-- 排班筛选条件 -->
          <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="88px">
            <el-form-item label="开始日期" prop="startDate">
              <el-date-picker
                v-model="queryParams.startDate"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择开始日期">
              </el-date-picker>
            </el-form-item>
            <el-form-item label="结束日期" prop="endDate">
              <el-date-picker
                v-model="queryParams.endDate"
                type="date"
                value-format="yyyy-MM-dd"
                placeholder="选择结束日期">
              </el-date-picker>
            </el-form-item>
            <el-form-item label="部门" prop="department">
              <el-select v-model="queryParams.department" placeholder="选择部门" clearable>
                <el-option
                  v-for="dept in deptOptions"
                  :key="dept.value"
                  :label="dept.label"
                  :value="dept.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="警员类型" prop="officerType">
              <el-select v-model="queryParams.officerType" placeholder="选择警员类型" clearable>
                <el-option label="民警" value="民警"></el-option>
                <el-option label="辅警" value="辅警"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
              <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>

          <!-- 排班结果表格 -->
          <el-table
            v-loading="loading"
            :data="scheduleData"
            border
            stripe
            style="width: 100%; margin-top: 15px;"
            @row-click="handleRowClick"
            highlight-current-row>
            <el-table-column type="index" label="序号" width="50" align="center" />
            <el-table-column prop="officerName" label="警员姓名" width="100" align="center" />
            <el-table-column prop="officerType" label="执勤类型" width="80" align="center" />
            <el-table-column prop="department" label="所属部门" width="120" align="center" />
            <el-table-column
              v-for="(day, index) in dateRange"
              :key="index"
              :label="formatDate(day)"
              align="center"
              min-width="110">
              <template slot-scope="scope">
                <el-popover
                  placement="top"
                  width="200"
                  trigger="hover"
                  :content="getScheduleDetail(scope.row, day)">
                  <div
                    slot="reference"
                    class="schedule-cell"
                    :class="getScheduleCellClass(scope.row, day)"
                    @click.stop="manualAdjust(scope.row, day)"
                  >
                    {{ getScheduleText(scope.row, day) }}
                  </div>
                </el-popover>
              </template>
            </el-table-column>
            <el-table-column prop="totalHours" label="总排班时长" width="100" align="center" />
            <el-table-column prop="totalShifts" label="总班次数" width="80" align="center" />
          </el-table>

          <!-- 分页 -->
          <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getScheduleList"
          />
        </el-card>
      </el-col>
    </el-row>


    <!-- 人工调整排班对话框 -->
    <el-dialog title="排班调整" :visible.sync="adjustDialogVisible" width="500px" append-to-body>
      <el-form :model="adjustForm" label-width="80px">
        <el-form-item label="警员" prop="officerName">
          <el-input v-model="adjustForm.officerName" disabled />
        </el-form-item>
        <el-form-item label="日期" prop="date">
          <el-input v-model="adjustForm.dateStr" disabled />
        </el-form-item>
        <el-form-item label="班次" prop="shiftId">
          <el-select v-model="adjustForm.shiftId" placeholder="选择班次">
            <el-option
              v-for="shift in shiftOptions"
              :key="shift.id"
              :label="shift.shiftName"
              :value="shift.id">
              <span style="float: left">{{ shift.shiftName }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ shift.timePeriod }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="调整原因" prop="reason">
          <el-input
            type="textarea"
            v-model="adjustForm.reason"
            placeholder="请输入调整原因"
            maxlength="200"
            show-word-limit
            rows="3">
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="adjustDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitAdjustment">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 生成排班确认对话框 -->
    <el-dialog title="生成排班" :visible.sync="generateDialogVisible" width="500px" append-to-body>
      <div>此操作将根据算法生成新的排班方案，可能会覆盖已有排班。是否继续？</div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="generateDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="confirmGenerateSchedule">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 算法参数设置对话框 -->
    <el-dialog title="算法参数设置" :visible.sync="paramDialogVisible" width="600px" append-to-body>
      <el-form :model="algorithmParams" label-width="150px">
        <el-form-item label="连续工作天数上限" prop="maxConsecutiveWorkDays">
          <el-input-number v-model="algorithmParams.maxConsecutiveWorkDays" :min="1" :max="7" />
        </el-form-item>
        <el-form-item label="每周最大工作天数" prop="maxWorkDaysPerWeek">
          <el-input-number v-model="algorithmParams.maxWorkDaysPerWeek" :min="3" :max="7" />
        </el-form-item>
        <el-form-item label="最小休息时间(小时)" prop="minRestHours">
          <el-input-number v-model="algorithmParams.minRestHours" :min="8" :max="24" />
        </el-form-item>
        <el-form-item label="警力需求系数" prop="demandFactor">
          <el-slider v-model="algorithmParams.demandFactor" :min="0.5" :max="1.5" :step="0.1" show-stops />
        </el-form-item>
        <el-form-item label="公平性权重" prop="fairnessWeight">
          <el-slider v-model="algorithmParams.fairnessWeight" :min="0" :max="1" :step="0.1" show-stops />
        </el-form-item>
        <el-form-item label="技能匹配权重" prop="skillMatchWeight">
          <el-slider v-model="algorithmParams.skillMatchWeight" :min="0" :max="1" :step="0.1" show-stops />
        </el-form-item>
        <el-form-item label="考虑历史排班数据">
          <el-switch v-model="algorithmParams.considerHistoricalData" />
        </el-form-item>
        <el-form-item label="考虑警员偏好">
          <el-switch v-model="algorithmParams.considerOfficerPreferences" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="resetAlgorithmParams">重置默认参数</el-button>
        <el-button @click="paramDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="confirmParamSettings">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { parseTime } from '@/utils/ruoyi'
import Pagination from "@/components/Pagination";
import OfficerStats from "./components/OfficerStats";
import {
  listSchedule,
  listOfficers,
  listShifts,
  listDepartments,
  generateSchedule,
  adjustSchedule,
  exportSchedule,
  getAlgorithmRecommendParams,
  generateAISchedule
} from "@/api/bussiness/scheduling";

// 导入勤务规划相关API
import {
  listEquipment
} from "@/api/bussiness/duty";

export default {
  name: "IntelligentScheduling",
  components: {
    Pagination,
    OfficerStats
  },
  data() {
    return {
      // 遮罩层
      loading: false,
      // 总条数
      total: 0,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        startDate: this.getDefaultStartDate(),
        endDate: this.getDefaultEndDate(),
        department: undefined,
        officerType: undefined
      },
      // 当前选中行
      selectedRow: null,
      selectedOfficerId: null,
      selectedOfficerInfo: {},
      // 部门选项
      deptOptions: [],
      // 班次选项
      shiftOptions: [],
      // 排班数据
      scheduleData: [],
      // 日期范围
      dateRange: [],
      // 调整对话框
      adjustDialogVisible: false,
      adjustForm: {
        officerId: null,
        officerName: '',
        date: null,
        dateStr: '',
        shiftId: null,
        reason: ''
      },
      // 生成排班对话框
      generateDialogVisible: false,
      // 参数设置对话框
      paramDialogVisible: false,
      // 算法参数
      algorithmParams: {
        maxConsecutiveWorkDays: 5,
        maxWorkDaysPerWeek: 5,
        minRestHours: 12,
        demandFactor: 1.0,
        fairnessWeight: 0.7,
        skillMatchWeight: 0.3,
        considerHistoricalData: true,
        considerOfficerPreferences: true
      },
      // 勤务规划表单
      dutyPlanForm: {
        name: '',
        dutyType: '',
        scenario: '',
        timeRange: [],
        equipment: [],
        routeId: null,
        patrolPointIds: []
      },
      // Mock巡逻线路数据
      mockRoutes: [
        {
          id: 1,
          name: '城区中心巡逻线路',
          type: 'daily',
          distance: 3.5,
          duration: 45,
          points: [1, 2, 3, 4, 5]
        },
        {
          id: 2,
          name: '校园安全巡逻线路',
          type: 'key_area',
          distance: 2.1,
          duration: 30,
          points: [6, 7, 8, 9]
        },
        {
          id: 3,
          name: '商圈巡逻线路',
          type: 'daily',
          distance: 4.2,
          duration: 60,
          points: [10, 11, 12, 13, 14]
        },
        {
          id: 4,
          name: '交通枢纽巡逻线路',
          type: 'key_area',
          distance: 3.0,
          duration: 40,
          points: [15, 16, 17, 18]
        },
        {
          id: 5,
          name: '特殊事件巡逻线路',
          type: 'special_event',
          distance: 5.5,
          duration: 75,
          points: [1, 5, 10, 15, 19, 20]
        }
      ],
      // Mock巡逻点数据
      mockPatrolPoints: [
        { id: 1, name: '人民广场检查点', type: 'checkpoint', location: '城区中心' },
        { id: 2, name: '东大街值守点', type: 'guardpost', location: '城区东部' },
        { id: 3, name: '西大街监控点', type: 'monitor', location: '城区西部' },
        { id: 4, name: '南大街检查点', type: 'checkpoint', location: '城区南部' },
        { id: 5, name: '北大街值守点', type: 'guardpost', location: '城区北部' },
        { id: 6, name: '校门口检查点', type: 'checkpoint', location: '学校大门' },
        { id: 7, name: '教学楼监控点', type: 'monitor', location: '教学区' },
        { id: 8, name: '宿舍区值守点', type: 'guardpost', location: '学生宿舍区' },
        { id: 9, name: '操场巡逻点', type: 'key_area', location: '校园操场' },
        { id: 10, name: '百货商场检查点', type: 'checkpoint', location: '商业中心' },
        { id: 11, name: '步行街监控点', type: 'monitor', location: '步行商业街' },
        { id: 12, name: '地下商场值守点', type: 'guardpost', location: '地下商城' },
        { id: 13, name: '餐饮区监控点', type: 'monitor', location: '餐饮集中区' },
        { id: 14, name: '夜市巡逻点', type: 'key_area', location: '夜间商业区' },
        { id: 15, name: '火车站检查点', type: 'checkpoint', location: '火车站' },
        { id: 16, name: '公交枢纽值守点', type: 'guardpost', location: '公交总站' },
        { id: 17, name: '地铁站监控点', type: 'monitor', location: '地铁站' },
        { id: 18, name: '出租车站点', type: 'guardpost', location: '出租车候车区' },
        { id: 19, name: '活动现场检查点', type: 'checkpoint', location: '临时活动区' },
        { id: 20, name: '重点设施巡逻点', type: 'key_area', location: '重要基础设施' }
      ],
      // 巡逻点列表
      patrolPoints: [],
      // 勤务明细列表
      dutyDetails: [],
      // 装备列表
      equipmentList: [],
      // 装备分配记录
      equipmentAssignments: [],
      // 当前激活的标签
      activeTab: 'patrol_routes'
    };
  },
  created() {
    this.getScheduleList();
    this.getDeptList();
    this.getShiftList();
    this.generateDateRange();

    // 初始化勤务数据
    // this.getPatrolPoints();
    // this.getDutyDetails();
    // this.getEquipmentList();
  },
  methods: {
    // 获取默认开始日期 (当前周的周一)
    getDefaultStartDate() {
      const now = new Date();
      const day = now.getDay() || 7; // 获取星期几，周日为0转为7
      const date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1 - day);
      return parseTime(date, '{y}-{m}-{d}');
    },
    // 获取默认结束日期 (当前开始日期加6天，即一周)
    getDefaultEndDate() {
      const startDate = new Date(this.getDefaultStartDate());
      const endDate = new Date(startDate);
      endDate.setDate(startDate.getDate() + 6);
      return parseTime(endDate, '{y}-{m}-{d}');
    },
    // 生成日期范围数组
    generateDateRange() {
      if (!this.queryParams.startDate || !this.queryParams.endDate) {
        return;
      }
      const start = new Date(this.queryParams.startDate);
      const end = new Date(this.queryParams.endDate);
      const range = [];
      let current = new Date(start);

      while (current <= end) {
        range.push(new Date(current));
        current.setDate(current.getDate() + 1);
      }
      this.dateRange = range;
    },
    // 格式化日期为 MM/DD (周x)
    formatDate(date) {
      const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
      const month = date.getMonth() + 1;
      const day = date.getDate();
      const weekday = weekdays[date.getDay()];
      return `${month}/${day < 10 ? '0' + day : day}\n(周${weekday})`;
    },
    // 获取部门列表
    getDeptList() {
      listDepartments().then(response => {
        if (response.code === 200) {
          this.deptOptions = response.data.map(item => {
            return { value: item.deptId, label: item.deptName };
          });
        } else {
          this.$message.error("获取部门列表失败");
        }
      });
    },
    // 获取班次列表
    getShiftList() {
      listShifts().then(response => {
        if (response.code === 200) {
          this.shiftOptions = response.data;
        } else {
          this.$message.error("获取班次列表失败");
          // 使用默认数据作为备选
          this.shiftOptions = [
            { id: 1, shiftName: '早班', timePeriod: '08:00-16:00' },
            { id: 2, shiftName: '中班', timePeriod: '16:00-24:00' },
            { id: 3, shiftName: '夜班', timePeriod: '00:00-08:00' },
            { id: 4, shiftName: '白班', timePeriod: '09:00-17:00' },
            { id: 5, shiftName: '晚班', timePeriod: '17:00-01:00' },
            { id: 6, shiftName: '休息', timePeriod: '全天' }
          ];
        }
      });
    },
    // 获取排班列表
    getScheduleList() {
      this.loading = true;

      const params = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize,
        startDate: this.queryParams.startDate,
        endDate: this.queryParams.endDate,
        department: this.queryParams.department,
        officerType: this.queryParams.officerType
      };

      listSchedule(params).then(response => {
        if (response.code === 200) {
          // 处理后端返回的排班数据
          this.processScheduleData(response.data);
          this.total = response.data ? response.data.length : 0; // 总数为返回的警员数
        } else {
          this.$message.error("获取排班数据失败");
          // 使用模拟数据作为备选
          const mockData = this.generateMockData();
          this.scheduleData = mockData;
          this.total = mockData.length;
        }
        this.loading = false;
      }).catch(() => {
        // 出错时使用模拟数据
        const mockData = this.generateMockData();
        this.scheduleData = mockData;
        this.total = mockData.length;
        this.loading = false;
      });
    },
    // 处理排班数据
    processScheduleData(data) {
      // 转换后端返回的数据格式为前端所需格式
      this.scheduleData = data.map(officer => {
        // 如果schedule字段已经是对象，直接使用；否则，尝试解析它
        const schedule = officer.schedule || {};

        // 计算总工时和总班次数
        let totalHours = officer.totalHours || 0;
        let totalShifts = officer.totalShifts || 0;

        // 如果后端未提供总工时和总班次数，需要自行计算
        if (!officer.totalHours || !officer.totalShifts) {
          totalHours = 0;
          totalShifts = 0;

          // 遍历日期范围计算
          this.dateRange.forEach(day => {
            const dayStr = parseTime(day, '{y}-{m}-{d}');
            const daySchedule = schedule[dayStr];

            if (daySchedule && daySchedule.shiftName && daySchedule.shiftName !== '休息' && daySchedule.shiftName !== '未排班') {
              totalShifts++;
              // 计算工作时长
              if (daySchedule.timePeriod && daySchedule.timePeriod !== '全天') {
                totalHours += this.calculateHours(daySchedule.timePeriod);
              }
            }
          });
        }

        return {
          officerId: officer.officerId,
          officerName: officer.officerName,
          officerType: officer.officerType,
          department: officer.department,
          schedule: schedule,
          totalHours: totalHours,
          totalShifts: totalShifts
        };
      });
    },
    // 生成模拟数据
    generateMockData() {
      const officers = [
        { officerId: 1, officerName: '张三', officerType: '民警', department: '交通一大队' },
        { officerId: 2, officerName: '李四', officerType: '民警', department: '交通一大队' },
        { officerId: 3, officerName: '王五', officerType: '民警', department: '交通二大队' },
        { officerId: 4, officerName: '赵六', officerType: '辅警', department: '交通二大队' },
        { officerId: 5, officerName: '钱七', officerType: '辅警', department: '交通三大队' }
      ];

      return officers.map(officer => {
        const schedule = {};
        let totalHours = 0;
        let totalShifts = 0;

        this.dateRange.forEach(day => {
          const dayStr = parseTime(day, '{y}-{m}-{d}');
          const randomShiftIndex = Math.floor(Math.random() * 6) + 1;
          const shift = this.shiftOptions.find(s => s.id === randomShiftIndex) ||
                       { id: randomShiftIndex, shiftName: `班次${randomShiftIndex}`, timePeriod: '未知' };

          if (randomShiftIndex !== 6) { // 不是休息
            totalShifts++;
            // 计算工作时长
            const hours = this.calculateHours(shift.timePeriod);
            totalHours += hours;
          }

          schedule[dayStr] = {
            shiftId: randomShiftIndex,
            shiftName: shift.shiftName,
            timePeriod: shift.timePeriod
          };
        });

        return {
          ...officer,
          schedule,
          totalHours,
          totalShifts
        };
      });
    },
    // 计算工作时长
    calculateHours(timePeriod) {
      if (timePeriod === '全天') return 0;

      const [start, end] = timePeriod.split('-');
      const startHour = parseInt(start.split(':')[0]);
      const endHour = parseInt(end.split(':')[0]);

      // 处理跨日的情况
      if (endHour < startHour) {
        return (24 - startHour) + endHour;
      } else {
        return endHour - startHour;
      }
    },
    // 获取排班单元格文本
    getScheduleText(row, day) {
      const dayStr = parseTime(day, '{y}-{m}-{d}');
      if (row.schedule && row.schedule[dayStr]) {
        return row.schedule[dayStr].shiftName || '未排班';
      }
      return '未排班';
    },
    // 获取排班单元格详情
    getScheduleDetail(row, day) {
      const dayStr = parseTime(day, '{y}-{m}-{d}');
      if (row.schedule && row.schedule[dayStr]) {
        const shift = row.schedule[dayStr];
        // 如果有时间段就显示班次名称和时间段，否则只显示班次名称
        if (shift.timePeriod) {
          return `${shift.shiftName} (${shift.timePeriod})`;
        }
        return shift.shiftName || '未排班';
      }
      return '未安排排班';
    },
    // 获取排班单元格样式
    getScheduleCellClass(row, day) {
      const dayStr = parseTime(day, '{y}-{m}-{d}');
      if (row.schedule && row.schedule[dayStr]) {
        const shiftName = row.schedule[dayStr].shiftName;

        // 根据班次名称判断返回不同的样式
        if (shiftName && shiftName.includes('早班')) return 'shift-morning';
        if (shiftName && shiftName.includes('中班')) return 'shift-afternoon';
        if (shiftName && shiftName.includes('夜班')) return 'shift-night';
        if (shiftName && shiftName.includes('白班')) return 'shift-day';
        if (shiftName && shiftName.includes('晚班')) return 'shift-evening';
        if (shiftName && shiftName.includes('休息')) return 'shift-rest';

      }
      return '';
    },
    // 处理行点击事件
    handleRowClick(row) {
      this.selectedRow = row;
      this.selectedOfficerId = row.officerId;
      this.selectedOfficerInfo = {
        officerId: row.officerId,
        officerName: row.officerName,
        officerType: row.officerType,
        department: row.department,
        officerCode: row.officerCode || `CODE${row.officerId}`
      };
    },
    // 刷新警员统计
    refreshOfficerStats() {
      // 触发子组件刷新
      if (this.selectedOfficerId) {
        this.$nextTick(() => {
          // 子组件会自行处理刷新逻辑
        });
      }
    },
    // 查询按钮
    handleQuery() {
      this.queryParams.pageNum = 1;
      // 确保在查询前更新日期范围
      this.generateDateRange();
      this.getScheduleList();
    },
    // 重置按钮
    resetQuery() {
      this.resetForm("queryForm");
      this.queryParams.startDate = this.getDefaultStartDate();
      this.queryParams.endDate = this.getDefaultEndDate();
      this.handleQuery();
    },
    // 刷新排班
    refreshSchedule() {
      this.getScheduleList();
      this.$message.success("排班数据已刷新");
    },
    // 处理人工调整
    handleManualAdjust() {
      if (!this.selectedRow) {
        this.$message.warning('请先选择一名警员');
        return;
      }

      // 默认选择第一个日期进行调整
      if (this.dateRange.length > 0) {
        this.manualAdjust(this.selectedRow, this.dateRange[0]);
      }
    },
    // 人工调整排班
    manualAdjust(row, day) {
      const dayStr = parseTime(day, '{y}-{m}-{d}');
      // 获取当前已设置的班次ID
      let currentShiftId = null;
      if (row.schedule && row.schedule[dayStr] && row.schedule[dayStr].shiftId) {
        currentShiftId = row.schedule[dayStr].shiftId;
      }

      this.adjustForm = {
        officerId: row.officerId,
        officerName: row.officerName,
        date: day,
        dateStr: dayStr,
        shiftId: currentShiftId,
        reason: ''
      };
      this.adjustDialogVisible = true;
    },
    // 提交调整
    submitAdjustment() {
      adjustSchedule(this.adjustForm).then(response => {
        if (response.code === 200) {
          this.$message.success("排班调整已保存");
          this.adjustDialogVisible = false;
          // 重新获取排班数据
          this.getScheduleList();
        } else {
          this.$message.error(response.msg || "排班调整保存失败");
        }
      }).catch(() => {
        this.$message.error("排班调整保存失败，请稍后再试");
      });
    },
    // 智能排班
    generateSchedule() {
      // 先获取算法推荐参数
      getAlgorithmRecommendParams().then(response => {
        if (response.code === 200) {
          this.algorithmParams = response.data;
        }
        this.paramDialogVisible = true;
      }).catch(() => {
        // 使用默认参数
        this.paramDialogVisible = true;
      });
    },
    // 确认参数设置
    confirmParamSettings() {
      this.paramDialogVisible = false;
      this.generateDialogVisible = true;
    },
    // 确认生成排班
    confirmGenerateSchedule() {
      this.generateDialogVisible = false;
      this.loading = true;

      const params = {
        startDate: this.queryParams.startDate,
        endDate: this.queryParams.endDate,
        department: this.queryParams.department,
        officerType: this.queryParams.officerType,
        algorithmParams: this.algorithmParams
      };

      generateSchedule(params).then(response => {
        if (response.code === 200) {
          this.$message.success("智能排班方案已生成");
          // 重新获取排班数据
          this.getScheduleList();
        } else {
          this.$message.error(response.msg || "生成排班方案失败");
          this.loading = false;
        }
      }).catch(() => {
        this.$message.error("生成排班方案失败，请稍后再试");
        this.loading = false;
      });
    },
    // 重置算法参数
    resetAlgorithmParams() {
      this.algorithmParams = {
        maxConsecutiveWorkDays: 5,
        maxWorkDaysPerWeek: 5,
        minRestHours: 12,
        demandFactor: 1.0,
        fairnessWeight: 0.7,
        skillMatchWeight: 0.3,
        considerHistoricalData: true,
        considerOfficerPreferences: true
      };
      this.$message.info("已重置为默认参数");
    },
    // 导出排班表
    exportSchedule() {
      const params = {
        startDate: this.queryParams.startDate,
        endDate: this.queryParams.endDate,
        department: this.queryParams.department,
        officerType: this.queryParams.officerType
      };

      exportSchedule(params).then(response => {
        this.download(response);
      }).catch(() => {
        this.$message.error("导出排班表失败，请稍后再试");
      });
    },
    // 下载文件
    download(res) {
      const blob = new Blob([res], { type: 'application/vnd.ms-excel' });
      const fileName = '排班表_' + parseTime(new Date(), '{y}{m}{d}') + '.xlsx';

      if ('download' in document.createElement('a')) {
        const link = document.createElement('a');
        link.download = fileName;
        link.style.display = 'none';
        link.href = URL.createObjectURL(blob);
        document.body.appendChild(link);
        link.click();
        URL.revokeObjectURL(link.href);
        document.body.removeChild(link);
      } else {
        navigator.msSaveBlob(blob, fileName);
      }
    },
    // 刷新勤务规划
    refreshDutyPlan() {
      this.resetDutyPlanForm();
      // this.getPatrolPoints();
      // this.getDutyDetails();
      // this.getEquipmentList();
      this.$message.success("勤务规划数据已重置");
    },
    // 处理勤务规划点击事件
    handleDutyPlanClick(row) {
      this.dutyPlanForm = JSON.parse(JSON.stringify(row));
      // 模拟根据规划获取巡逻点
      this.getPatrolPoints();
      // 模拟根据规划获取勤务明细
      this.getDutyDetails();
    },
    // 编辑勤务规划
    editDutyPlan(row) {
      this.dutyPlanForm = JSON.parse(JSON.stringify(row));
    },
    // 删除勤务规划
    deleteDutyPlan(row) {
      const index = this.dutyPlans.findIndex(item => item.id === row.id);
      if (index > -1) {
        this.dutyPlans.splice(index, 1);
        this.$message.success("规划已删除");
      }
    },
    // 格式化勤务类型
    formatDutyType(row) {
      const dutyTypeMap = {
        'regular_patrol': '常规巡逻',
        'fixed_post': '定点值守',
        'traffic_control': '交通管控',
        'security_patrol': '治安巡查',
        'emergency': '应急处突'
      };
      return dutyTypeMap[row.dutyType] || row.dutyType;
    },
    // 获取勤务规划列表
    getDutyPlans() {
      // 使用模拟数据，不再从后端获取
      this.dutyPlans = [
        { id: 1, name: '城区常规巡逻', dutyType: 'regular_patrol', scenario: 'urban_patrol' },
        { id: 2, name: '校园安全巡查', dutyType: 'security_patrol', scenario: 'campus_security' },
        { id: 3, name: '交通路口值守', dutyType: 'fixed_post', scenario: 'traffic_intersection' }
      ];
    },
    // 重置勤务规划表单
    resetDutyPlanForm() {
      this.dutyPlanForm = {
        name: '',
        dutyType: '',
        scenario: '',
        timeRange: [],
        equipment: [],
        routeId: null,
        patrolPointIds: []
      };
    },
    // 获取巡逻点列表
    getPatrolPoints() {
      // 使用mockPatrolPoints作为巡逻点数据源
      this.patrolPoints = [...this.mockPatrolPoints];
    },
    // 获取勤务明细列表
    getDutyDetails() {
      // 使用模拟数据
      this.dutyDetails = [
        { id: 1, date: '2023-07-10', timeSlot: '08:00-12:00', location: '东门', dutyType: '定点值守', officers: '张三, 李四', equipment: '对讲机, 执法记录仪' },
        { id: 2, date: '2023-07-10', timeSlot: '14:00-18:00', location: '西门', dutyType: '定点值守', officers: '王五, 赵六', equipment: '对讲机, 执法记录仪' },
        { id: 3, date: '2023-07-11', timeSlot: '08:00-18:00', location: '城区主干道', dutyType: '常规巡逻', officers: '张三, 王五', equipment: '对讲机, 警棍, 警用手电' },
      ];
    },
    // 编辑勤务明细
    editDutyDetail(row) {
      // 此处应打开编辑对话框，只是展示AI生成的明细，不需要编辑
      this.$message.info("查看勤务明细: " + row.id);
    },
    // 删除勤务明细
    deleteDutyDetail(row) {
      // 从本地列表中移除
      const index = this.dutyDetails.findIndex(item => item.id === row.id);
      if (index > -1) {
        this.dutyDetails.splice(index, 1);
        this.$message.success("勤务明细已删除");
      }
    },
    // 获取装备列表
    getEquipmentList() {
      listEquipment().then(response => {
        if (response.code === 200) {
          this.equipmentList = response.data;
        } else {
          this.$message.error("获取装备列表失败");
          // 使用模拟数据
          this.equipmentList = [
            { id: 1, name: '对讲机', type: '通信装备', quantity: 20, status: '正常' },
            { id: 2, name: '防弹背心', type: '防护装备', quantity: 10, status: '正常' },
            { id: 3, name: '执法记录仪', type: '记录装备', quantity: 15, status: '正常' },
            { id: 4, name: '警棍', type: '防卫装备', quantity: 25, status: '正常' },
            { id: 5, name: '警用手电', type: '照明装备', quantity: 30, status: '正常' }
          ];
        }
      }).catch(() => {
        // 使用模拟数据
        this.equipmentList = [
          { id: 1, name: '对讲机', type: '通信装备', quantity: 20, status: '正常' },
          { id: 2, name: '防弹背心', type: '防护装备', quantity: 10, status: '正常' },
          { id: 3, name: '执法记录仪', type: '记录装备', quantity: 15, status: '正常' },
          { id: 4, name: '警棍', type: '防卫装备', quantity: 25, status: '正常' },
          { id: 5, name: '警用手电', type: '照明装备', quantity: 30, status: '正常' }
        ];
      });

      // 获取装备分配记录
      this.getEquipmentAssignments();
    },
    // 获取装备分配记录
    getEquipmentAssignments() {
      // 模拟数据
      this.equipmentAssignments = [
        { id: 1, equipmentName: '对讲机', officerName: '张三', assignTime: '2023-07-10 08:00', returnTime: '2023-07-10 18:00', status: '已归还' },
        { id: 2, equipmentName: '执法记录仪', officerName: '李四', assignTime: '2023-07-10 08:00', returnTime: '', status: '使用中' },
        { id: 3, equipmentName: '防弹背心', officerName: '王五', assignTime: '2023-07-11 08:00', returnTime: '', status: '使用中' }
      ];
    },
    // 分配装备
    assignEquipment(row) {
      // 此处应打开分配对话框，暂时只是提示
      this.$message.info("分配装备: " + row.name);
    },
    // 查看装备详情
    viewEquipmentDetail(row) {
      // 此处应打开详情对话框，暂时只是提示
      this.$message.info("查看装备详情: " + row.name);
    },
    // 查看巡逻点详情
    viewPatrolPointDetail(row) {
      // 此处应打开详情对话框，暂时只是提示
      this.$message.info("查看巡逻点详情: " + row.name);
    },
    // 获取巡逻路线列表
    getPatrolRoutes() {
      // 不再从后端获取，使用本地数据
      if (!this.dutyPlanForm.routes) {
        this.dutyPlanForm.routes = [];
      }
    },
    // 提交勤务规划数据给后端大模型
    submitDutyPlanToAI() {
      if (!this.dutyPlanForm.name) {
        this.$message.warning("请输入勤务名称");
        return;
      }
      if (!this.dutyPlanForm.dutyType) {
        this.$message.warning("请选择执勤方式");
        return;
      }
      if (!this.dutyPlanForm.scenario) {
        this.$message.warning("请选择勤务场景");
        return;
      }
      if (!this.dutyPlanForm.timeRange || this.dutyPlanForm.timeRange.length < 2) {
        this.$message.warning("请设置勤务时段");
        return;
      }
      if (!this.dutyPlanForm.equipment || this.dutyPlanForm.equipment.length === 0) {
        this.$message.warning("请至少选择一项安保装备");
        return;
      }
      if (!this.dutyPlanForm.routeId) {
        this.$message.warning("请选择巡逻线路");
        return;
      }
      if (!this.dutyPlanForm.patrolPointIds || this.dutyPlanForm.patrolPointIds.length === 0) {
        this.$message.warning("请选择巡逻点");
        return;
      }

      this.$confirm('确认提交当前规划参数给智能排班系统生成排班方案？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.loading = true;

        // 获取选中的巡逻线路和巡逻点详细信息
        const selectedRoute = this.mockRoutes.find(r => r.id === this.dutyPlanForm.routeId) || {};
        const selectedPatrolPoints = this.mockPatrolPoints.filter(p => this.dutyPlanForm.patrolPointIds.includes(p.id));

        // 整合巡逻路线和巡逻点数据
        const planParams = {
          ...this.dutyPlanForm,
          route: {
            id: selectedRoute.id,
            name: selectedRoute.name,
            type: selectedRoute.type,
            distance: selectedRoute.distance,
            duration: selectedRoute.duration
          },
          patrolPoints: selectedPatrolPoints,
          dateRange: {
            startDate: this.queryParams.startDate,
            endDate: this.queryParams.endDate
          },
          officerParams: {
            department: this.queryParams.department,
            officerType: this.queryParams.officerType
          },
          algorithmParams: this.algorithmParams
        };

        // 提交给后端AI模型处理
        generateAISchedule(planParams).then(response => {
          if (response.code === 200) {
            this.$message.success("智能排班方案已生成");
            // 刷新排班数据
            this.getScheduleList();
            // 显示AI生成的勤务明细
            this.getDutyDetails();
            // 自动切换到勤务安排明细标签
            this.activeTab = 'duty_details';
          } else {
            this.$message.error(response.msg || "智能排班失败");
          }
          this.loading = false;
        }).catch(() => {
          this.$message.error("智能排班失败，请稍后再试");
          this.loading = false;
        });
      }).catch(() => {
        // 用户取消操作
      });
    },
    // 巡逻线路选择变更处理
    handleRouteChange(routeId) {
      if (routeId) {
        // 根据选择的线路自动选择关联的巡逻点
        const route = this.mockRoutes.find(r => r.id === routeId);
        if (route) {
          this.dutyPlanForm.patrolPointIds = [...route.points];
        }
      } else {
        // 清空巡逻点选择
        this.dutyPlanForm.patrolPointIds = [];
      }
    },
    // 格式化路线类型
    formatRouteType(row) {
      const routeTypeMap = {
        'daily': '日常巡逻',
        'key_area': '重点区域',
        'special_event': '特殊事件'
      };
      return routeTypeMap[row.type] || row.type;
    },
  },
  computed: {
    // 获取当前选中的线路
    selectedRoute() {
      if (this.dutyPlanForm.routeId) {
        return this.mockRoutes.find(r => r.id === this.dutyPlanForm.routeId) || {};
      }
      return {};
    },
    // 获取过滤后的巡逻点列表（基于选中的线路）
    filteredPatrolPoints() {
      if (this.dutyPlanForm.routeId) {
        const route = this.mockRoutes.find(r => r.id === this.dutyPlanForm.routeId);
        if (route && route.points) {
          return this.mockPatrolPoints.filter(point => route.points.includes(point.id));
        }
      }
      return this.mockPatrolPoints;
    }
  }
};
</script>

<style lang="scss" scoped>
.schedule-cell {
  height: 36px;
  line-height: 36px;
  font-weight: bold;
  color: #fff;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s;
  margin: 2px;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  letter-spacing: 1px;

  &:hover {
    opacity: 0.9;
    transform: scale(1.05);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }

  &.shift-morning {
    background-color: #67C23A; // 绿色 - 早班
    background-image: linear-gradient(45deg, #67C23A, #85CE61);
    box-shadow: 0 3px 6px rgba(103, 194, 58, 0.4);
  }

  &.shift-afternoon {
    background-color: #E6A23C; // 黄色 - 中班
    background-image: linear-gradient(45deg, #E6A23C, #F5C77B);
    box-shadow: 0 3px 6px rgba(230, 162, 60, 0.4);
  }

  &.shift-night {
    background-color: #409EFF; // 蓝色 - 夜班
    background-image: linear-gradient(45deg, #409EFF, #69B9FF);
    box-shadow: 0 3px 6px rgba(64, 158, 255, 0.4);
  }

  &.shift-day {
    background-color: #19BE6B; // 亮绿色 - 白班
    background-image: linear-gradient(45deg, #19BE6B, #5ADAA9);
    box-shadow: 0 3px 6px rgba(25, 190, 107, 0.4);
  }

  &.shift-evening {
    background-color: #FF9900; // 橙色 - 晚班
    background-image: linear-gradient(45deg, #FF9900, #FFBB33);
    box-shadow: 0 3px 6px rgba(255, 153, 0, 0.4);
  }

  &.shift-rest {
    background-color: #909399; // 灰色 - 休息
    background-image: linear-gradient(45deg, #909399, #C0C4CC);
    box-shadow: 0 3px 6px rgba(144, 147, 153, 0.4);
    color: #fff;
  }
}

.el-form-item {
  margin-bottom: 15px;
}

.box-card {
  margin-bottom: 15px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}
.clearfix:after {
  clear: both;
}

.el-table {
  .cell {
    padding: 0px 5px;
  }
}

.el-table .el-table__row td {
  padding: 4px 0;

  &:hover {
    background-color: #f5f7fa;
  }
}

// 当前选中行的高亮样式
.el-table .current-row td {
  background-color: #ecf5ff !important;
}

.shift-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin: 15px 0;
  padding: 10px;
  border-radius: 4px;
  background-color: #f9f9f9;
  border: 1px solid #eaeaea;

  .legend-title {
    font-weight: bold;
    margin-right: 15px;
    color: #606266;
  }

  .legend-item {
    display: inline-flex;
    align-items: center;
    margin-right: 15px;
    margin-bottom: 5px;

    .legend-color {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 4px;
      margin-right: 5px;
      vertical-align: middle;
      box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);

      &.shift-morning {
        background-image: linear-gradient(to right, #67C23A, #85CE61);
      }

      &.shift-afternoon {
        background-image: linear-gradient(to right, #E6A23C, #F5C77B);
      }

      &.shift-night {
        background-image: linear-gradient(to right, #409EFF, #69B9FF);
      }

      &.shift-day {
        background-image: linear-gradient(to right, #19BE6B, #5ADAA9);
      }

      &.shift-evening {
        background-image: linear-gradient(to right, #FF9900, #FFBB33);
      }

      &.shift-rest {
        background-image: linear-gradient(to right, #909399, #C0C4CC);
      }
    }

    .legend-text {
      display: inline-block;
      font-size: 14px;
      color: #606266;
    }
  }
}

/* 新增样式 */
.map-container {
  height: 500px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #f8f8f8;
  position: relative;
  overflow: hidden;
}

.map-placeholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #909399;

  i {
    font-size: 64px;
    margin-bottom: 10px;
  }

  p {
    font-size: 16px;
    margin: 10px 0;
  }

  .map-hint {
    font-size: 12px;
    color: #c0c4cc;
  }
}

.route-map-container {
  height: 400px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #f8f8f8;
  position: relative;
  overflow: hidden;
  margin-bottom: 20px;
}

.patrol-points-list {
  padding: 0 15px;

  h4 {
    margin: 10px 0;
    color: #303133;
    font-size: 16px;
  }
}

.duty-plan-options {
  margin-bottom: 20px;
}

.saved-duty-plans {
  margin-top: 20px;
}

h4 {
  margin: 15px 0;
  font-weight: 500;
  color: #303133;
}

.route-detail {
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fb;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.route-info {
  margin-top: 10px;
}

.route-info p {
  margin: 8px 0;
  color: #606266;
}

.route-info strong {
  font-weight: 500;
  color: #303133;
  margin-right: 5px;
}
</style>
